﻿using Engine;
using Game;
using Mekiasm.Interface;

namespace Mekiasm
{
    public class ComponentMekCraftTable : ComponentEnergyMachine
    {
        public override IDynamicCraft CraftDevice => MekCraftingRecipe.FindCraftDevice(typeof(MekCraftTable));

        public override bool CheckResultCapacity => false;

        public override int GetSlotCapacity(int slotIndex, int value)
        {
            if (slotIndex == 10) return 0;
            if (slotIndex == 9) return 0;
            return base.GetSlotCapacity(slotIndex, value);
        }

        public override void AddSlotItems(int slotIndex, int value, int count)
        {
            base.AddSlotItems(slotIndex, value, count);
            DoCraft();
        }
        /// <summary>
        /// 用于合成后，赋予物品数据
        /// </summary>
        /// <param name="slotIndex"></param>
        /// <param name="value"></param>
        /// <param name="count"></param>
        /// <param name="processCount"></param>
        /// <param name="processedValue"></param>
        /// <param name="processedCount"></param>
        public override void ProcessSlotItems(int slotIndex, int value, int count, int processCount, out int processedValue, out int processedCount)
        {
            int slotCount = GetSlotCount(slotIndex);
            int slotValue = GetSlotValue(slotIndex);
            if (slotCount > 0 && slotValue != 0)
            {
                SubsystemBlockBehavior[] blockBehaviors = base.Project.FindSubsystem<SubsystemBlockBehaviors>(throwOnError: true).GetBlockBehaviors(Terrain.ExtractContents(slotValue));
                foreach (SubsystemBlockBehavior subsystemBlockBehavior in blockBehaviors)
                {
                    int processInventoryItemCapacity = subsystemBlockBehavior.GetProcessInventoryItemCapacity(this, slotIndex, value);
                    if (processInventoryItemCapacity > 0)
                    {
                        subsystemBlockBehavior.ProcessInventoryItem(this, slotIndex, value, count, MathUtils.Min(processInventoryItemCapacity, processCount), out processedValue, out processedCount);
                        return;
                    }
                }
            }
            processedValue = value;
            processedCount = count;
            if (CraftDevice.ResultSlotIndies.Length > 0)
            {
                foreach (var i in CraftDevice.ResultSlotIndies)
                {
                    if (slotIndex == i)
                    {
                        var block = BlocksManager.Blocks[Terrain.ExtractContents(value)];
                        if (block is MekBlock mek)
                        {
                            processedValue = mek.GetCraftedResultValue(value);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 合成后执行一次获取物品被合成剩下物品的方法
        /// </summary>
        /// <param name="slotIndex"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public override int RemoveSlotItems(int slotIndex, int count)
        {
            int num;
            if (CurrentRecipe != null && (slotIndex == 10 || slotIndex == 9))
            {
                var resultValue = CurrentRecipe.Results[0];
                var resultCount = CurrentRecipe.ResultCounts[0];
                int minNum = 0;//可以合成多少份
                int maxStacking = BlocksManager.Blocks[Terrain.ExtractContents(resultValue)].GetMaxStacking(resultValue);
                for (int i = 0; i < 9; i++)
                {
                    if (Slots[i].Count == 0) continue;
                    if (minNum == 0) minNum = MathUtils.Max(Slots[i].Count, minNum);
                    else minNum = MathUtils.Min(Slots[i].Count, minNum);
                }

                int maxMinNum = maxStacking / resultCount;//合成多少份后到达格子上限
                //超出最大堆叠数，取不超过最大堆叠数的最大值
                if (minNum > maxMinNum) minNum = maxMinNum;
                num = minNum * resultCount;
                for (int i = 0; i < 9; i++)
                {
                    //减去合成的物品
                    var slot = Slots[i];
                    if (slot.Count > 0)
                    {
                        var block = BlocksManager.Blocks[Terrain.ExtractContents(slot.Value)];
                        if (block is MekBlock mek)
                        {
                            int v = mek.GetCraftedRemainValue(slot.Value);
                            if (v == 0)
                            {
                                slot.Count -= minNum;
                            }
                            else
                            {
                                slot.Value = v;
                            }
                        }
                        else
                        {
                            slot.Count -= minNum;
                        }
                    }
                }
                OnSlotChange();
                DoCraft();
            }
            else
            {
                num = base.RemoveSlotItems(slotIndex, count);
            }
            DoCraft();
            return num;
        }
        public override void DoCraft()
        {
            if (CurrentRecipe != null)
            {
                int minNum = 0;
                for (int i = 0; i < 9; i++)
                {
                    if (Slots[i].Count == 0) continue;
                    if (minNum == 0) minNum = Engine.MathUtils.Max(Slots[i].Count, minNum);
                    else minNum = Engine.MathUtils.Min(Slots[i].Count, minNum);
                }
                for (int i = 0; i < CraftDevice.RemainSlotIndies.Length; i++)
                {
                    var slot = Slots[CraftDevice.RemainSlotIndies[i]];
                    if (AquireItems(CraftDevice.RemainSlotIndies[i], CurrentRecipe.Remains[i], CurrentRecipe.RemainCounts[i]))
                    {
                        slot.Value = CurrentRecipe.Remains[i];
                        slot.Count = CurrentRecipe.RemainCounts[i];
                    }
                }
                for (int i = 0; i < CraftDevice.ResultSlotIndies.Length; i++)
                {
                    var slot = Slots[CraftDevice.ResultSlotIndies[i]];
                    if (AquireItems(CraftDevice.ResultSlotIndies[i], CurrentRecipe.Results[i], CurrentRecipe.ResultCounts[i]))
                    {
                        slot.Value = CurrentRecipe.Results[i];
                        slot.Count = CurrentRecipe.ResultCounts[i] * minNum;
                    }
                }
            }
            else
            {
                for (int i = 0; i < CraftDevice.ResultSlotIndies.Length; i++)
                {
                    var slot = Slots[CraftDevice.ResultSlotIndies[i]];
                    slot.Value = 0;
                    slot.Count = 0;
                }
                for (int i = 0; i < CraftDevice.RemainSlotIndies.Length; i++)
                {
                    var slot = Slots[CraftDevice.RemainSlotIndies[i]];
                    slot.Value = 0;
                    slot.Count = 0;
                }
            }
        }

    }
}
